﻿/*
 * md5.hpp
 *
 *  Created on: 2017年6月5日
 *      Author: work
 */

#ifndef _DM_UTILITY_MD5_HPP_
#define _DM_UTILITY_MD5_HPP_

#include <dm/export.hpp>

#ifndef DM_API_MISC
#define DM_API_MISC DM_API_IMPORT
#endif

#include <dm/types.hpp>
#include <fstream>
#include <string>

namespace dm{
namespace utility{

class DM_API_MISC CMd5{
	CMd5( const CMd5& );
	CMd5& operator=( const CMd5& );
public:
	CMd5();
	CMd5( const void* input, size_t length );
	CMd5( const std::string& str );
	CMd5( std::ifstream& in );
	void update( const void* input, size_t length );
	void update( const std::string& str );
	void update( std::ifstream& in );
	const dm::uint8* digest();
	std::string toString();
	void reset();

private:
	void update(const dm::uint8* input, size_t length);
	void final();
	void transform(const dm::uint8 block[64]);
	void encode(const dm::uint32* input, dm::uint8* output, size_t length);
	void decode(const dm::uint8* input, dm::uint32* output, size_t length);
	std::string bytesToHexString(const dm::uint8* input, size_t length);

private:
	dm::uint32 m_state[4];	/* state (ABCD) */
	dm::uint32 m_count[2];	/* number of bits, modulo 2^64 (low-order word first) */
	dm::uint8 m_buffer[64];	/* input buffer */
	dm::uint8 m_digest[16];	/* message digest */
	bool m_finished;		/* calculate finished ? */
};

}
}

#endif /* INCLUDE_DM_UTILITY_MD5_HPP_ */
